using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using JGSY.CMS.LowCode.Platform.Infrastructure.Configuration;

namespace JGSY.CMS.LowCode.Platform.Controllers
{
    /// <summary>
    /// 应用设置管理控制器
    /// 提供对 appsettings.json 配置的统一 API 接口
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    public class AppSettingsController : ControllerBase
    {
        private readonly IAppSettingsManager _appSettingsManager;
        private readonly IConfigurationService _configurationService;
        private readonly ILogger<AppSettingsController> _logger;

        public AppSettingsController(
            IAppSettingsManager appSettingsManager,
            IConfigurationService configurationService,
            ILogger<AppSettingsController> logger)
        {
            _appSettingsManager = appSettingsManager ?? throw new ArgumentNullException(nameof(appSettingsManager));
            _configurationService = configurationService ?? throw new ArgumentNullException(nameof(configurationService));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }

        /// <summary>
        /// 获取指定键的配置值
        /// </summary>
        /// <param name="key">配置键</param>
        /// <returns>配置值</returns>
        [HttpGet("value/{key}")]
        public IActionResult GetValue(string key)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(key))
                {
                    return BadRequest("配置键不能为空");
                }

                var value = _appSettingsManager.GetStringValue(key);
                
                _logger.LogDebug("Configuration value retrieved: {Key} = {Value}", key, value);
                
                return Ok(new { key, value });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting configuration value for key: {Key}", key);
                return StatusCode(500, "获取配置值时发生错误");
            }
        }

        /// <summary>
        /// 获取指定配置节的所有配置项
        /// </summary>
        /// <param name="section">配置节名称</param>
        /// <returns>配置项字典</returns>
        [HttpGet("section/{section}")]
        public IActionResult GetSection(string section)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(section))
                {
                    return BadRequest("配置节名称不能为空");
                }

                var settings = _appSettingsManager.GetSection(section);
                
                _logger.LogDebug("Configuration section retrieved: {Section} with {Count} items", section, settings.Count);
                
                return Ok(settings);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting configuration section: {Section}", section);
                return StatusCode(500, "获取配置节时发生错误");
            }
        }

        /// <summary>
        /// 获取数据库配置
        /// </summary>
        /// <returns>数据库配置</returns>
        [HttpGet("database")]
        public IActionResult GetDatabaseConfig()
        {
            try
            {
                var config = _configurationService.GetDatabaseConfig();
                
                // 隐藏敏感信息（连接字符串中的密码）
                var safeConfig = new
                {
                    config.Type,
                    ConnectionString = MaskConnectionString(config.ConnectionString),
                    config.ConnectionTimeout,
                    config.CommandTimeout,
                    config.EnableSensitiveDataLogging
                };
                
                _logger.LogDebug("Database configuration retrieved");
                
                return Ok(safeConfig);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting database configuration");
                return StatusCode(500, "获取数据库配置时发生错误");
            }
        }

        /// <summary>
        /// 获取缓存配置
        /// </summary>
        /// <returns>缓存配置</returns>
        [HttpGet("cache")]
        public IActionResult GetCacheConfig()
        {
            try
            {
                var config = _configurationService.GetCacheConfig();
                
                // 隐藏敏感信息
                var safeConfig = new
                {
                    config.Type,
                    config.TestEnabled,
                    config.TestTTL,
                    config.TestKeyPrefix,
                    Redis = new
                    {
                        Url = MaskUrl(config.Redis.Url),
                        config.Redis.Db,
                        config.Redis.MaxRetries,
                        config.Redis.RetryDelay,
                        config.Redis.ConnectionTimeout,
                        config.Redis.CommandTimeout
                    }
                };
                
                _logger.LogDebug("Cache configuration retrieved");
                
                return Ok(safeConfig);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting cache configuration");
                return StatusCode(500, "获取缓存配置时发生错误");
            }
        }

        /// <summary>
        /// 获取安全配置（隐藏敏感信息）
        /// </summary>
        /// <returns>安全配置</returns>
        [HttpGet("security")]
        public IActionResult GetSecurityConfig()
        {
            try
            {
                var config = _configurationService.GetSecurityConfig();
                
                // 隐藏敏感信息
                var safeConfig = new
                {
                    config.EnableMFA,
                    config.EnableThreatDetection,
                    config.DeviceFingerprintEnabled,
                    config.AppName,
                    config.TotpIssuer,
                    config.SessionTimeout,
                    config.MaxLoginAttempts,
                    config.LockoutDuration,
                    config.PasswordMinLength,
                    config.RequireStrongPassword,
                    Jwt = new
                    {
                        config.Jwt.Issuer,
                        config.Jwt.Audience,
                        config.Jwt.ExpiryMinutes,
                        config.Jwt.RefreshTokenExpiryDays
                    },
                    RateLimit = config.RateLimit
                };
                
                _logger.LogDebug("Security configuration retrieved (sensitive data masked)");
                
                return Ok(safeConfig);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting security configuration");
                return StatusCode(500, "获取安全配置时发生错误");
            }
        }

        /// <summary>
        /// 获取 CORS 配置
        /// </summary>
        /// <returns>CORS 配置</returns>
        [HttpGet("cors")]
        public IActionResult GetCorsConfig()
        {
            try
            {
                var config = _configurationService.GetCorsConfig();
                
                _logger.LogDebug("CORS configuration retrieved");
                
                return Ok(config);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting CORS configuration");
                return StatusCode(500, "获取 CORS 配置时发生错误");
            }
        }

        /// <summary>
        /// 获取文件上传配置
        /// </summary>
        /// <returns>文件上传配置</returns>
        [HttpGet("upload")]
        public IActionResult GetFileUploadConfig()
        {
            try
            {
                var config = _configurationService.GetFileUploadConfig();
                
                _logger.LogDebug("File upload configuration retrieved");
                
                return Ok(config);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting file upload configuration");
                return StatusCode(500, "获取文件上传配置时发生错误");
            }
        }

        /// <summary>
        /// 获取应用程序基础信息
        /// </summary>
        /// <returns>应用程序信息</returns>
        [HttpGet("info")]
        public IActionResult GetAppInfo()
        {
            try
            {
                var info = _configurationService.GetAppInfo();
                
                _logger.LogDebug("Application information retrieved");
                
                return Ok(info);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting application information");
                return StatusCode(500, "获取应用程序信息时发生错误");
            }
        }

        /// <summary>
        /// 获取所有可公开的配置设置
        /// </summary>
        /// <returns>公开配置设置</returns>
        [HttpGet("public")]
        public IActionResult GetPublicSettings()
        {
            try
            {
                var publicSettings = new Dictionary<string, object>
                {
                    ["Environment"] = _configurationService.GetEnvironmentName(),
                    ["AppInfo"] = _configurationService.GetAppInfo(),
                    ["CORS"] = _configurationService.GetCorsConfig(),
                    ["Upload"] = _configurationService.GetFileUploadConfig()
                };
                
                _logger.LogDebug("Public settings retrieved");
                
                return Ok(publicSettings);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting public settings");
                return StatusCode(500, "获取公开设置时发生错误");
            }
        }

        /// <summary>
        /// 检查配置键是否存在
        /// </summary>
        /// <param name="key">配置键</param>
        /// <returns>是否存在</returns>
        [HttpGet("exists/{key}")]
        public IActionResult CheckKeyExists(string key)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(key))
                {
                    return BadRequest("配置键不能为空");
                }

                var exists = _appSettingsManager.HasKey(key);
                
                _logger.LogDebug("Configuration key existence checked: {Key} = {Exists}", key, exists);
                
                return Ok(new { key, exists });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error checking if configuration key exists: {Key}", key);
                return StatusCode(500, "检查配置键是否存在时发生错误");
            }
        }

        /// <summary>
        /// 重新加载配置
        /// </summary>
        /// <returns>操作结果</returns>
        [HttpPost("reload")]
        public IActionResult ReloadConfiguration()
        {
            try
            {
                _appSettingsManager.Reload();
                
                _logger.LogInformation("Configuration reloaded successfully");
                
                return Ok(new { message = "配置已重新加载", timestamp = DateTime.UtcNow });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error reloading configuration");
                return StatusCode(500, "重新加载配置时发生错误");
            }
        }

        /// <summary>
        /// 隐藏连接字符串中的敏感信息
        /// </summary>
        /// <param name="connectionString">连接字符串</param>
        /// <returns>处理后的连接字符串</returns>
        private static string MaskConnectionString(string connectionString)
        {
            if (string.IsNullOrWhiteSpace(connectionString))
                return "";

            // 简单的密码隐藏逻辑
            var patterns = new[] { "Password=", "Pwd=", "password=" };
            var result = connectionString;
            
            foreach (var pattern in patterns)
            {
                var index = result.IndexOf(pattern, StringComparison.OrdinalIgnoreCase);
                if (index >= 0)
                {
                    var start = index + pattern.Length;
                    var end = result.IndexOf(';', start);
                    if (end == -1) end = result.Length;
                    
                    var password = result.Substring(start, end - start);
                    result = result.Replace(password, "****");
                }
            }
            
            return result;
        }

        /// <summary>
        /// 隐藏 URL 中的敏感信息
        /// </summary>
        /// <param name="url">URL</param>
        /// <returns>处理后的 URL</returns>
        private static string MaskUrl(string url)
        {
            if (string.IsNullOrWhiteSpace(url))
                return "";

            // 简单的 URL 用户名密码隐藏逻辑
            if (url.Contains('@'))
            {
                var atIndex = url.LastIndexOf('@');
                var protocolEnd = url.IndexOf("://");
                if (protocolEnd > 0 && atIndex > protocolEnd)
                {
                    var protocol = url.Substring(0, protocolEnd + 3);
                    var hostPart = url.Substring(atIndex);
                    return protocol + "****" + hostPart;
                }
            }
            
            return url;
        }
    }
}
